package com.gobrs.async.core.autoconfig;

import com.gobrs.async.core.GobrsAsync;
import com.gobrs.async.core.TaskFlow;
import com.gobrs.async.core.callback.*;
import com.gobrs.async.core.config.*;
import com.gobrs.async.core.engine.RuleEngine;
import com.gobrs.async.core.engine.RuleParseEngine;
import com.gobrs.async.core.engine.RulePostProcessor;
import com.gobrs.async.core.engine.RuleThermalLoad;
import com.gobrs.async.core.holder.BeanHolder;
import com.gobrs.async.core.threadpool.GobrsAsyncThreadPoolFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * 自动配置
 */
@Configuration
@EnableConfigurationProperties({GobrsAsyncProperties.class, RuleConfig.class, LogConfig.class})
@ConditionalOnProperty(prefix = GobrsAsyncProperties.PREFIX, value = "enable", matchIfMissing = true, havingValue = "true")
public class GobrsAutoConfiguration {

    private GobrsAsyncProperties gobrsAsyncProperties;

    public GobrsAutoConfiguration() {}

    public GobrsAutoConfiguration(GobrsAsyncProperties gobrsAsyncProperties) {
        this.gobrsAsyncProperties = gobrsAsyncProperties;
    }

    /**
     * 任务流
     */
    @Bean
    public TaskFlow taskFlow() {
        return new TaskFlow();
    }

    /**
     * 异步线程池工厂
     */
    @Bean
    public GobrsAsyncThreadPoolFactory gobrsAsyncThreadPoolFactory(GobrsAsyncProperties grabrsAsyncProperties) {
        return new GobrsAsyncThreadPoolFactory(grabrsAsyncProperties);
    }

    /**
     * 规则引擎
     */
    @Bean
    @ConditionalOnMissingBean(value = RuleEngine.class)
    public RuleEngine ruleEngine() {
        return new RuleParseEngine<>();
    }

    /**
     * 配置工厂
     */
    @Bean
    public ConfigFactory configFactory(GobrsAsyncProperties gobrsAsyncProperties) {
        return new ConfigFactory(gobrsAsyncProperties);
    }

    /**
     * 配置缓存管理
     */
    @ConditionalOnBean(ConfigFactory.class)
    @Bean
    public ConfigManager configManager() {
        return new ConfigManager();
    }

    /**
     * 规则后置处理器
     */
    @Bean
    public RulePostProcessor ruleEnginePostProcessor(ConfigManager configManager) {
        return new RulePostProcessor(configManager);
    }

    @Bean
    public GobrsAsync gobrsAsync() {
        return new GobrsAsync();
    }

    @Bean
    public BeanHolder gobrsSpring() {
        return new BeanHolder();
    }

    /**
     * 异步任务异常拦截器
     */
    @Bean
    @ConditionalOnMissingBean(value = AsyncTaskExceptionInterceptor.class)
    public AsyncTaskExceptionInterceptor asyncExceptionInterceptor() {
        return new DefaultAsyncExceptionInterceptor();
    }

    /**
     * 异步任务前置拦截器
     */
    @Bean
    @ConditionalOnMissingBean(value = AsyncTaskPreInterceptor.class)
    public AsyncTaskPreInterceptor asyncTaskPreInterceptor() {
        return new DefaultAsyncTaskPreInterceptor();
    }

    /**
     * 异步任务后置拦截器
     */
    @Bean
    @ConditionalOnMissingBean(value = AsyncTaskPostInterceptor.class)
    public AsyncTaskPostInterceptor asyncTaskPostInterceptor() {
        return new DefaultAsyncTaskPostInterceptor();
    }

    /**
     * 规则热加载器
     */
    @Bean
    public RuleThermalLoad ruleThermalLoading() {
        return new RuleThermalLoad();
    }

}
